#ifndef FIELDCIRCUITCOUPLING_H
#define FIELDCIRCUITCOUPLING_H

#include <vector>
#include <complex>
#include <string>
#include <memory>
#include <iostream>
// 包含独立的Vector_3D类
#include "Vector_3D.h"

namespace FieldCircuitCoupling {

// Forward declarations
class CircuitModel;
class FieldSolverInterface;
class CouplingManager;

// Complex value type for electromagnetic quantities
typedef std::complex<double> Complex;

// Port definition for field-circuit coupling
typedef struct {
    int portId;               // Unique port identifier
    Vector_3D position;        // Position in 3D space
    Vector_3D orientation[2];  // Orientation vectors (E and H directions)
    std::string circuitNode1; // Connected circuit node 1
    std::string circuitNode2; // Connected circuit node 2
    double impedance;         // Characteristic impedance
    bool isVoltagePort;       // true for voltage-driven port, false for current-driven
    std::vector<size_t> basisFunctionIndices; // Indices of basis functions associated with this port
    std::vector<Complex> basisFunctionWeights; // Weights for the basis functions
} CouplingPort;

// Circuit element types
enum class CircuitElementType {
    RESISTOR,
    CAPACITOR,
    INDUCTOR,
    VOLTAGE_SOURCE,
    CURRENT_SOURCE,
    RESISTOR_MODEL,
    CAPACITOR_MODEL,
    INDUCTOR_MODEL,
    TRANSMISSION_LINE,
    JUNCTION,
    PORT
};

// Circuit element definition
typedef struct {
    std::string id;                  // Element identifier
    CircuitElementType type;         // Element type
    std::string node1;               // First node
    std::string node2;               // Second node
    Complex value;                   // Element value (R, C, L, etc.)
    std::vector<std::string> models; // Associated models
} CircuitElement;

// Simulation configuration
typedef struct {
    double frequency;                // Simulation frequency
    double timeStep;                 // Time step for transient simulation
    double endTime;                  // End time for transient simulation
    int maxIterations;               // Maximum iterations for convergence
    double convergenceTolerance;     // Convergence tolerance
    bool isTransient;                // Transient or frequency domain
    std::string couplingMode;        // "weak" or "strong"
} SimulationConfig;

// Matrix block structure for MoM coupling
typedef struct {
    std::vector<std::vector<Complex>> Z_field;       // Field domain impedance matrix
    std::vector<std::vector<Complex>> Z_circuit;     // Circuit domain impedance matrix
    std::vector<std::vector<Complex>> Z_coupling;    // Coupling impedance matrix
    std::vector<Complex> V_field;                   // Field domain voltage vector
    std::vector<Complex> V_circuit;                 // Circuit domain voltage vector
} CouplingMatrix;

// Interface for the 3D field solver
class FieldSolverInterface {
public:
    virtual ~FieldSolverInterface() = default;
    
    // Initialize the field solver
    virtual bool initialize(const std::string& configFile) = 0;
    
    // Update frequency for frequency domain simulation
    virtual bool updateFrequency(double frequency) = 0;
    
    // Get impedance matrix for the field domain
    virtual bool getImpedanceMatrix(std::vector<std::vector<Complex>>& Z_field) = 0;
    
    // Get coupling matrix between field and circuit
    virtual bool getCouplingMatrix(const std::vector<CouplingPort>& ports, 
                                 std::vector<std::vector<Complex>>& Z_coupling) = 0;
    
    // Set currents from circuit solution
    virtual bool setPortCurrents(const std::vector<CouplingPort>& ports, 
                               const std::vector<Complex>& currents) = 0;
    
    // Get fields at observation points
    virtual bool getFieldsAt(const std::vector<Vector_3D>& points, 
                           std::vector<Complex>& eFields, 
                           std::vector<Complex>& hFields) = 0;
    
    // Solve the field problem with given excitations
    virtual bool solve(const std::vector<Complex>& excitations) = 0;
    
    // Get the number of unknowns in the field solver
    virtual size_t getNumUnknowns() = 0;
};

// Circuit model class for 2D circuit simulation
class CircuitModel {
public:
    CircuitModel();
    ~CircuitModel();
    
    // Add a circuit element
    bool addElement(const CircuitElement& element);
    
    // Initialize the circuit model
    bool initialize();
    
    // Update frequency for frequency domain analysis
    bool updateFrequency(double frequency);
    
    // Get the circuit impedance matrix
    bool getImpedanceMatrix(std::vector<std::vector<Complex>>& Z_circuit);
    
    // Set port voltages from field solution
    bool setPortVoltages(const std::vector<CouplingPort>& ports, 
                       const std::vector<Complex>& voltages);
    
    // Get port currents
    bool getPortCurrents(const std::vector<CouplingPort>& ports, 
                       std::vector<Complex>& currents);
    
    // Solve the circuit with given boundary conditions
    bool solve(const std::vector<std::pair<int, Complex>>& boundaryConditions);
    
    // Export circuit solution to file
    bool exportSolution(const std::string& filename);
    
    // Import circuit from file
    bool importFromFile(const std::string& filename);
    
    // Get the number of nodes in the circuit
    size_t getNumNodes();
    
    // Get the number of ports in the circuit
    size_t getNumPorts();
    
private:
    std::vector<CircuitElement> elements;
    std::vector<std::string> nodeNames;
    std::vector<CircuitElement> ports;
    bool initialized;
    double currentFrequency;
    
    // Internal methods
    void buildNodeMap();
    void stampMatrix(std::vector<std::vector<Complex>>& matrix, 
                    const CircuitElement& element);
};

// Main coupling manager class
class CouplingManager {
public:
    CouplingManager();
    ~CouplingManager();
    
    // Initialize the coupling manager
    bool initialize(const SimulationConfig& config);
    
    // Set the field solver interface
    bool setFieldSolver(std::shared_ptr<FieldSolverInterface> solver);
    
    // Set the circuit model
    bool setCircuitModel(std::shared_ptr<CircuitModel> circuit);
    
    // Add a coupling port
    bool addCouplingPort(const CouplingPort& port);
    
    // Setup the coupling matrices
    bool setupCouplingMatrices();
    
    // Solve the coupled problem
    bool solve();
    
    // Run transient simulation
    bool runTransientSimulation();
    
    // Run frequency domain simulation
    bool runFrequencySweep(double startFreq, double endFreq, int numPoints);
    
    // Export the coupled solution
    bool exportSolution(const std::string& filename);
    
    // Get fields at observation points
    bool getFieldsAt(const std::vector<Vector_3D>& points, 
                   std::vector<Complex>& eFields, 
                   std::vector<Complex>& hFields);
    
    // Get convergence information
    bool getConvergenceInfo(int& iterations, double& residual);
    
    // Reset the solver
    void reset();
    
private:
    std::shared_ptr<FieldSolverInterface> fieldSolver;
    std::shared_ptr<CircuitModel> circuitModel;
    std::vector<CouplingPort> couplingPorts;
    SimulationConfig config;
    CouplingMatrix couplingMatrix;
    bool initialized;
    int convergenceIterations;
    double finalResidual;
    
    // Internal methods
    bool solveStrongCoupling();
    bool solveWeakCoupling();
    bool updateCouplingMatrices();
    double calculateResidual(const std::vector<Complex>& previousSolution, 
                           const std::vector<Complex>& currentSolution);
};

// Factory function to create a field solver interface
extern std::shared_ptr<FieldSolverInterface> createFieldSolverInterface();

// Utility functions
extern bool exportCouplingData(const std::string& filename, 
                             const CouplingMatrix& matrix,
                             const std::vector<Complex>& solution);

extern bool importCouplingData(const std::string& filename, 
                             CouplingMatrix& matrix,
                             std::vector<Complex>& solution);

// DLL export functions for C API
extern "C" {
    __declspec(dllexport) void* CreateCouplingManager();
    __declspec(dllexport) void DestroyCouplingManager(void* manager);
    __declspec(dllexport) bool InitializeCouplingManager(void* manager, const SimulationConfig* config);
    __declspec(dllexport) bool AddCouplingPort(void* manager, const CouplingPort* port);
    __declspec(dllexport) bool SolveCoupling(void* manager);
    __declspec(dllexport) bool ExportSolution(void* manager, const char* filename);
    __declspec(dllexport) bool RunFrequencySweep(void* manager, double startFreq, double endFreq, int numPoints);
}

} // namespace FieldCircuitCoupling

#endif // FIELDCIRCUITCOUPLING_H